/* $Id: VBoxMPDevExt.h $ */
/** @file
 * VBox Miniport device extension header
 */

/*
 * Copyright (C) 2011-2020 Oracle Corporation
 *
 * This file is part of VirtualBox Open Source Edition (OSE), as
 * available from http://www.virtualbox.org. This file is free software;
 * you can redistribute it and/or modify it under the terms of the GNU
 * General Public License (GPL) as published by the Free Software
 * Foundation, in version 2 as it comes in the "COPYING" file of the
 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
 */

#ifndef _WDDM_INCLUDE_COMMON_VBOXMPDEVEXT_H_
#define _WDDM_INCLUDE_COMMON_VBOXMPDEVEXT_H_

#include <ntddk.h>
#include <ntdef.h>

#include "common/VBoxMPIf.h"
#include "wddm/VBoxMPTypes.h"

extern BOOLEAN g_VBoxDisplayOnly;
typedef struct VBOXWDDM_EXT_GA *PVBOXWDDM_EXT_GA;

typedef struct VBOXWDDM_HWRESOURCES
{
    PHYSICAL_ADDRESS phVRAM;
    ULONG cbVRAM;
    ULONG ulApertureSize;

    PHYSICAL_ADDRESS phFIFO;
    ULONG cbFIFO;

    PHYSICAL_ADDRESS phIO;
    ULONG cbIO;

    PHYSICAL_ADDRESS phSysIO;
    ULONG cbSysIO;
} VBOXWDDM_HWRESOURCES, *PVBOXWDDM_HWRESOURCES;

typedef struct VBOXMP_COMMON
{
    int cDisplays;                      /* Number of displays. */

    UINT32 cbVRAM;                    /* The VRAM size. */

    PHYSICAL_ADDRESS phVRAM;            /* Physical VRAM base. */

    ULONG ulApertureSize;               /* Size of the LFB aperture (>= VRAM size). */

    UINT32 cbMiniportHeap;            /* The size of reserved VRAM for miniport driver heap.
                                         * It is at offset:
                                         *   cbAdapterMemorySize - VBOX_VIDEO_ADAPTER_INFORMATION_SIZE - cbMiniportHeap
                                         */
    void *pvMiniportHeap;               /* The pointer to the miniport heap VRAM.
                                         * This is mapped by miniport separately.
                                         */
    void *pvAdapterInformation;         /* The pointer to the last 4K of VRAM.
                                         * This is mapped by miniport separately.
                                         */
    BOOLEAN fAnyX;                      /* Unrestricted horizontal resolution flag. */
    UINT16 u16SupportedScreenFlags;   /* VBVA_SCREEN_F_* flags supported by the host. */
} VBOXMP_COMMON, *PVBOXMP_COMMON;

typedef struct
{
    LPVOID  RawBuf;
    LPWCH* AppNames;
    UINT    AppCount;
} HW_MONO_CURSOR_UNSUPPORTED_APPS;

typedef struct _VBOXMP_DEVEXT
{
    struct _VBOXMP_DEVEXT *pNext;               /* Next extension in the DualView extension list.
                                                * The primary extension is the first one.
                                                */
    PDEVICE_OBJECT pPDO;
    UNICODE_STRING RegKeyName;
    UNICODE_STRING VideoGuid;

    DWORD dwDrvCfgFlags;
    BOOLEAN f3DEnabled;
    BOOLEAN fComplexTopologiesEnabled;

   BOOL bVSyncTimerEnabled;
   volatile UINT32 fVSyncInVBlank;
   volatile LARGE_INTEGER VSyncTime;
   PEX_TIMER VSyncTimer;

    VBOXWDDM_GLOBAL_POINTER_INFO PointerInfo;

    VBOXVIDEO_HWTYPE enmHwType;
    VBOXWDDM_HWRESOURCES HwResources;
    VBOXWDDM_SOURCE aSources[VBOX_VIDEO_MAX_SCREENS];
    VBOXWDDM_TARGET aTargets[VBOX_VIDEO_MAX_SCREENS];

    union {
        /* Information that is only relevant to the primary device or is the same for all devices. */
        struct {
            VBOXMP_COMMON commonInfo;
            DXGKRNL_INTERFACE DxgkInterface;     /* Display Port handle and callbacks */
        } primary;

        /* Secondary device information. */
        struct {
            BOOLEAN bEnabled;                   /* Device enabled flag */
        } secondary;
    } u;

    PVBOXWDDM_EXT_GA pGa;                       /* Pointer to Gallium backend data. */

    UINT8* pvVisibleVram;
    ULONG cbVRAMCpuVisible;                     /* How much video memory is available for the CPU visible segment. */

    void *sysIORegisterBase;
    DWORD SysDisplaySourceId;

    HW_MONO_CURSOR_UNSUPPORTED_APPS HwMonoCursorUnsupportedApps;
    DEVICE_POWER_STATE AdapterPowerState;
    PEPROCESS dwmR0Process;
} VBOXMP_DEVEXT, *PVBOXMP_DEVEXT;

DECLINLINE(PVBOXMP_COMMON) VBoxCommonFromDeviceExt(PVBOXMP_DEVEXT pExt)
{
    return &pExt->u.primary.commonInfo;
}

DECLINLINE(ULONG) vboxWddmVramCpuVisibleSize(PVBOXMP_DEVEXT pDevExt)
{
    return pDevExt->cbVRAMCpuVisible;
}

DECLINLINE(ULONG) vboxWddmVramCpuVisibleSegmentSize(PVBOXMP_DEVEXT pDevExt)
{
    return vboxWddmVramCpuVisibleSize(pDevExt);
}

/* 128 MB */
DECLINLINE(ULONG) vboxWddmVramCpuInvisibleSegmentSize(PVBOXMP_DEVEXT pDevExt)
{
    RT_NOREF(pDevExt);
    return 128 * 1024 * 1024;
}

#endif
